package com.kr.weitao.util.mybatis;

import com.github.pagehelper.PageHelper;
import lombok.extern.log4j.Log4j2;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.util.Properties;

/** Created by Abel on 2017/6/12. */
@Log4j2
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnBean(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration {

  @Autowired private MybatisProperties properties;

  @Autowired(required = false)
  private Interceptor[] interceptors;

  @Autowired private ResourceLoader resourceLoader = new DefaultResourceLoader();

  @PostConstruct
  public void checkConfigFileExists() {
    if (this.properties.isCheckConfigLocation()) {
      Resource resource = this.resourceLoader.getResource(this.properties.getConfig());
      Assert.state(
          resource.exists(),
          "Cannot find config location: "
              + resource
              + " (please add config file or check your Mybatis "
              + "configuration)");
    }
  }

  @Bean(name = "sqlSessionFactory")
  @ConditionalOnMissingBean
  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    if (StringUtils.hasText(this.properties.getConfig())) {
      factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfig()));
    } else {
      if (this.interceptors != null && this.interceptors.length > 0) {
        factory.setPlugins(this.interceptors);
      }
      factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
      factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
      factory.setMapperLocations(this.properties.getMapperLocations());
    }
    return factory.getObject();
  }

  @Bean
  @ConditionalOnMissingBean
  public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
    return new SqlSessionTemplate(sqlSessionFactory, this.properties.getExecutorType());
  }

  /**
   * 分页插件
   *
   * @param dataSource
   * @return
   */
  @Bean
  public PageHelper pageHelper(DataSource dataSource) {
    log.info("注册MyBatis分页插件PageHelper");
    PageHelper pageHelper = new PageHelper();
    Properties p = new Properties();
    p.setProperty("offsetAsPageNum", "true");
    p.setProperty("rowBoundsWithCount", "true");
    p.setProperty("reasonable", "true");
    pageHelper.setProperties(p);
    return pageHelper;
  }
}
